/**********************************************************注意 IE 不支持 拉姆达表达式  IE下拉姆达表达式写法 'x=>x.num==3'******************************************************* */
/** 
 * Array where 仅支持 拉姆达 表达式  对应 List的 Where
 * @module where  仅支持 拉姆达 表达式
 * @param  仅支持 拉姆达 表达式 例如 'x=>x.num==3' || 'x=>x.num>3'
 */
Array.prototype.where = function () {
    if(this.length<=0) return [];
    var args = arguments[0].toString();
    var matches = args.match(/(\w)(\s+)?=>(.*)+/);
    if (!matches) {
        console.error('invalid expression.');
        return [];
    }
    var name = matches[1];
    var expression = matches[3];
    if (!this) return [];
    var result = [];
    var func = new Function(name, 'return ' + expression + ';');
    this.forEach(function (value, index, array) {
        if (func(value)) {
            result.push(value);
        }
    });
    return result;
}
/** 
 * Array whereFun 不支持拉姆达 表达式  对应 List的 Where
 * @module where  不支持拉姆达 表达式
 * @param  不支持拉姆达 传入函数  函数需要返回 boolean 值
 */
Array.prototype.whereFun = function () {
    if(this.length<=0) return [];
    if (arguments.length <= 0) {
        console.error('invalid function.');
        return [];
    }
    var func = arguments[0];
    if (!(func instanceof Function)) {
        console.error('invalid function.');
        return [];
    }
    var result = [];
    this.forEach(function (value, index, array) {
        if (func(value)) {
            result.push(value);
        }
    });
    return result;
}
/**
 * Array select 仅支持 拉姆达 表达式  对应 List的 Select
 * 
 * @module select 
 * @param 表达式 例如 x=>x.Name || x=> new {name:x.Name}
 */
Array.prototype.select = function () {
    if(this.length<=0) return [];
    var args = arguments[0].toString();
    var matches = args.match(/(\w)(\s+)?=>(.*)+/);
    if (!matches) {
        console.error('invalid expression .');
        return [];
    }
    var name = matches[1];
    var expression = matches[3];
    matches = expression.match(/\.(\w+)/);
    if (!matches) {
        console.error('invalid expression .');
        return [];
    }
    var result = [];
    if (expression.toString().indexOf('{') < 0) {
        var property = matches[1];
        this.forEach(function (value, index, array) {
            if (value[property]) {
                result.push(value[property]);
            }
        });
    } else {
        expression = expression.substring(expression.indexOf('{'), expression.length)
        var func = new Function(name, 'return ' + expression + ';');
        this.forEach(function (value, index, array) {
            result.push(func(value));
        });
    }
    return result;
}
/** 
 * Array selectFun 不支持 拉姆达 表达式  对应 List的 Select
 * @module select  不支持 拉姆达 表达式
 * @param  不支持拉姆达 传入函数  函数需要返回 值
 */
Array.prototype.selectFun = function () {
    if(this.length<=0) return [];
    if (arguments.length <= 0) {
        console.error('invalid function.');
        return [];
    }
    var func = arguments[0];
    if (!(func instanceof Function)) {
        console.error('invalid function.');
        return [];
    }
    var result = [];
    this.forEach(function (value, index, array) {
        result.push(func(value));
    });
    return result;
}
/** 
 * Array findFirst 仅支持 拉姆达 表达式  对应 List的 Find  返回第一个
 * @module where  仅支持 拉姆达 表达式
 * @param  仅支持 拉姆达 表达式 例如 x=>x.num==3 || x=>x.num>3
 */
Array.prototype.findFirst = function () {
    if(this.length<=0) return undefined;
    var args = arguments[0].toString();
    var matches = args.match(/(\w)(\s+)?=>(.*)+/);
    if (!matches) {
        console.error('invalid expression.');
        return undefined;
    }
    var name = matches[1];
    var expression = matches[3];
    if (!this) return [];
    var result = [];
    var func = new Function(name, 'return ' + expression + ';');
    this.forEach(function (value, index, array) {
        if (func(value)) {
            result.push(value);
        }
    });
    if (result.length > 0)
        return result[0]
    return undefined;
};
/** 
 * Array findFun 不支持拉姆达表达式  对应 List的 Find 返回第一个
 * @module findFun  不支持拉姆达 表达式
 * @param  不支持拉姆达 传入函数  函数需要返回 boolean 值
 */
Array.prototype.findFun = function () {
    if(this.length<=0) return undefined;
    if (arguments.length <= 0) {
        console.error('invalid function.');
        return [];
    }
    var func = arguments[0];
    if (!(func instanceof Function)) {
        console.error('invalid function.');
        return [];
    }
    var result = [];
    this.forEach(function (value, index, array) {
        if (func(value)) {
            result.push(value);
        }
    });
    if (result.length > 0)
        return result[0]
    return undefined;
};
/**
 * Array sum 仅支持 拉姆达 表达式  对应 List的 Sum
 * 
 * @module sum 
 * @param 表达式 例如 x=>x.num 
 */
Array.prototype.sum = function () {
    if(this.length<=0) return 0;
    var args = arguments[0].toString();
    var matches = args.match(/(\w)(\s+)?=>(.*)+/);
    if (!matches) {
        console.error('invalid expression.');
        return 0;
    }
    var name = matches[1];
    var expression = matches[3];
    if (!this) return 0;
    var result = 0;
    var func = new Function(name, 'return ' + expression + ';');
    this.forEach(function (value, index, array) {
        var num = func(value) * 1;
        if (isNaN(num)) {
            num = 0;
        }
        result += num;
    });
    return result;
};
/** 
 * Array sumFun 不支持 拉姆达 表达式  对应 List的 Sum
 * @module sumFun  不支持 拉姆达 表达式
 * @param  不支持拉姆达 传入函数  函数需要返回 值
 */
Array.prototype.sumFun = function () {
    if(this.length<=0) return 0;
    var result = 0;
    if (arguments.length <= 0) {
        console.error('invalid function.')
        return result;
    }
    var func = arguments[0];
    if (!(func instanceof Function)) {
        console.error('invalid function.');
        return result;
    }
    this.forEach(function (value, index, array) {
        var num = func(value) * 1;
        if (isNaN(num)) {
            num = 0;
        }
        result += num;
    });
    return result;
};
/**
 * Array distinct 仅支持 拉姆达 表达式  对应 List的 Distinct 【单个字段】 需要指定根据哪个字段去重
 * 
 * @module distinct 
 * @param 表达式 例如 x=>x.bar_code 
 */
Array.prototype.distinct = function () {
    if(this.length<=0) return [];
    var args = arguments[0].toString();
    var matches = args.match(/(\w)(\s+)?=>(.*)+/);
    if (!matches) {
        console.error('invalid expression .');
        return [];
    }
    var name = matches[1];
    var expression = matches[3];
    matches = expression.match(/\.(\w+)/);
    if (!matches) {
        console.error('invalid expression .');
        return [];
    }
    var property = matches[1];
    var result = [];
    this.forEach(function (value, index, array) {
        if (value[property]) {
            var add = true;
            for (var i = 0; i < result.length; i++) {
                if (value[property] == result[i][property]) {
                    add = false;
                    break;
                }
            }
            if (add) result.push(value);
        }
    });
    return result;
};
/**
 * Array distinctFun 不支持拉姆达表达式 【单个字段】 需要指定根据哪个字段去重
 * 
 * @module distinctFun 
 * @param 字段 
 */
Array.prototype.distinctFun = function () {
    if(this.length<=0) return [];
    if (arguments.length <= 0) {
        console.error('invalid fileds .');
        return [];
    }
    var args = arguments[0].toString();
    if (this.length <= 0) return [];

    if (!this[0][args]) {
        console.error('invalid fileds .');
        return [];
    }
    var result = [];
    this.forEach(function (value, index, array) {
        if (value[args]) {
            var add = true;
            for (var i = 0; i < result.length; i++) {
                if (value[args] == result[i][args]) {
                    add = false;
                    break;
                }
            }
            if (add) result.push(value);
        }
    });
    return result;
};
/** 
 * Array toJsonStr 转Json字符串
 * 
 * @module toJsonStr  转Json字符串
 * 
 */
Array.prototype.toJsonStr = function () {
    if (!Array.isArray(this)||this.length<=0) return "[]";
    return JSON.stringify(this);
};
/**
 * Array joins 仅支持 拉姆达 表达式  对应 string的 Join 【单个字段】
 * 
 * @module joins 
 * @param 表达式 例如 x=>x.Name || x=> new {name:x.Name}
 */
Array.prototype.joins = function () {
    if(this.length<=0) return "";
    var args = arguments[0].toString();
    var matches = args.match(/(\w)(\s+)?=>(.*)+/);
    if (!matches) {
        console.error('invalid expression .');
        return '';
    }
    var result = '';
    var expression = matches[3];
    matches = expression.match(/\.(\w+)/);
    if (!matches) {
        console.error('invalid expression .');
        return '';
    }
    var property = matches[1];
    var result = [];
    this.forEach(function (value, index, array) {
        if (value[property]) {
            var add = true;
            for (var i = 0; i < result.length; i++) {
                if (value[property] == result[i]) {
                    add = false;
                    break;
                }
            }
            if (add) result.push(value[property]);
        }
    });
    if (result.length > 0) {
        var str = '';
        result.forEach(function (value, index, array) {
            str = str + value + ",";
        });
        if (str.length > 0)
            str = str.substring(0, str.length - 1);
        return str;
    }
    return '';
};
/** 
 * Array joinsFun 不支持 拉姆达 表达式  对应 string的 Join 【单个字段】
 * @module joinsFun  不支持 拉姆达 表达式
 * @param  不支持拉姆达 传入函数  函数需要返回 值
 */
Array.prototype.joinsFun = function () {
    if(this.length<=0) return "";
    if (arguments.length <= 0) {
        console.error('invalid fileds .');
        return [];
    }
    var args = arguments[0].toString();
    if (this.length <= 0) return [];

    if (!this[0][args]) {
        console.error('invalid fileds .');
        return [];
    }
    var result = [];
    this.forEach(function (value, index, array) {
        if (value[args]) {
            var add = true;
            for (var i = 0; i < result.length; i++) {
                if (value[args] == result[i]) {
                    add = false;
                    break;
                }
            }
            if (add) result.push(value[args]);
        }
    });
    if (result.length > 0) {
        var str = '';
        result.forEach(function (value, index, array) {
            str = str + value + ",";
        });
        if (str.length > 0)
            str = str.substring(0, str.length - 1);
        return str;
    }
    return '';
};
/**
 * Array toJoinStr 仅支持数组内不含任何对象 输出字符串
 * 
 * @module toJoinStr 
 * 
 */
Array.prototype.toJoinStr = function () { 
    if (this.length > 0) {
        var str = '';
        this.forEach(function (value, index, array) {
            str = str + value + ",";
        });
        if (str.length > 0)
            str = str.substring(0, str.length - 1);
        return str;
    }
    return '';
};
/**
 * Array toDistinct 仅支持数组内不含任何对象 去重
 * 
 * @module toDistinct 
 * @param 字段 
 */
Array.prototype.toDistinct = function () {
    if (this.length > 0) return [];
    var result = [];
    this.forEach(function (value, index, array) {
        if (value) {
            var add = true;
            for (var i = 0; i < result.length; i++) {
                if (value == result[i]) {
                    add = false;
                    break;
                }
            }
            if (add) result.push(value);
        }
    });
    return result;
};